﻿using System;

using System.Collections.Generic;
using System.Text;
using PublicTransport.DAL;
using PublicTransport.Services.BO;
using PublicTransport.DAL.DTO;
using System.Threading;
using PublicTransport.Services.Enums;

namespace PublicTransport.Services
{
    /// <summary>  Trieda, ktorá dokáže vyhľadávať spoje
    /// 		   Je nutné zavolať najprv AsyncLoad pre prípravu  </summary>
    class PathSearchingService : IPathSearchService
    {

        /// <summary> DAO pre dosiahnuteľné stanice</summary>
        private ReacheableDao reacheableDao;
        private TimeTableDao timeTableDao;
        public event EventHandler DataLoaded;
        private bool dataLoaded = false;
        Thread loaderThread; 

        public PathSearchingService()
        {

        }

        /// <summary>   Zavolá predpripravenie dát, po ukončení prípravy zavolá event DataLoaded. </summary>
        public void AsyncLoad()
        {
            
            ThreadStart starter = new ThreadStart(LoadDao);
            loaderThread = new Thread(starter);
            loaderThread.IsBackground = true;
            loaderThread.Start();

        }

        /// <summary>   Metóda, ktorá pripraví dáta, je volaná asynchrónne </summary>
        private void LoadDao()
        {
            reacheableDao = new ReacheableDao();
            timeTableDao = new TimeTableDao();
            dataLoaded = true;
            if (DataLoaded != null)
               ThreadPool.QueueUserWorkItem(new WaitCallback(DoStuff));
        }


        private void DoStuff(object status)
        {
            DataLoaded(this, new EventArgs());
        }

        /// <summary>
        ///     Kľúčová metóda, ktorá navráti všetky možnosti presunu z jednej zastávka na druhú.
        /// </summary>
        ///
        /// <param name="startId">  Štartovná zastávka. </param>
        /// <param name="endId">    Cieľová zastávka. </param>
        /// <param name="time">     Čas v ktorom hľadáme spoj. </param>
        /// <param name="dayType">  Typ ďna. </param>
        ///
        /// <returns>   Nájdená cesta </returns>
        public List<List<PublicTransport.Services.Step2.Transit>> FindPath(int startId, int endId, int time, DayTypeEnum dayType)
        {
            if (loaderThread != null)
            {
                loaderThread.Join();
            }
            List<List<PublicTransport.Services.Step2.Transit>> result = new List<List<Step2.Transit>>();
            Step1 step1 = new Step1(startId, endId, reacheableDao);
            Step2 step2 = new Step2(timeTableDao);
            int countOfSteps = 0;
            do
            {
                countOfSteps++;
                List<List<NodeInfo>> results = step1.DoStep1();
                result.AddRange(step2.GetTimes2(results, time, dayType));

            } while (result.Count < 3 && countOfSteps<2);

            result.Sort(new PublicTransport.Services.TransitComparer());
            return result;

        }

    }
}
